Crochemore et al. proposed a bit-vector algorithm for the longest common subsequence(LCS) problem with four bit operations compared to the five bit operations of Allison and Dix(Allison-Dix Algorithm). The complexity of this algorithm is O(mn/w) time and O(m/w) space, where w is the word size of the machine.
int CIPR_Alg(char *stringA, char *stringB, int m, int n)
{
int i, j, bitStringCount, LCS = 0, carry, type, in, bitDo;
char matchTable[DATATYPE] = { FLASE };
unsigned char **alphbetString, *prevRow, *tempX, temp, **revAlphbetString;
bitStringCount = (int) ceil((double) m / BITSIZE);
prevRow = (unsigned char*) calloc(bitStringCount + 1, sizeof(unsigned char));
// Init the prev. row
tempX = (unsigned char*) calloc(bitStringCount + 1, sizeof(unsigned char));
//Init temp string X
memset(prevRow, (int) pow((float) 2, DATATYPE) - 1, bitStringCount + 1);
for (i = 1; i <= m; i++){
matchTable[stringA[i]] = TRUE;
}
for (i = 1; i <= n; i++){
matchTable[stringB[i]] = TRUE;
}// Mark the used alphbet
alphbetString = (unsigned char**) calloc(DATATYPE, sizeof(unsigned char*));
revAlphbetString = (unsigned char**) calloc(DATATYPE, sizeof(unsigned char*));
// Set the size of alphbet string
for (i = 0; i <= DATATYPE; i++){
if (matchTable[i] == TRUE){
alphbetString[i] = (unsigned char*) calloc(bitStringCount + 1, sizeof(unsigned char));
revAlphbetString[i] = (unsigned char*) calloc(bitStringCount + 1, sizeof(unsigned char));
}
}// Init the size of alphbet string which are used
for (i = 0; i < bitStringCount; i++){
for (j = 1; j <= BITSIZE; j++){
if (m%BITSIZE != 0 && (i == bitStringCount - 1) && (j > m%BITSIZE)){
break;
}
alphbetString[stringA[i*BITSIZE + j]][i + 1] += (int) pow((double) 2, (int) (BITSIZE - j));
}
}// Init the value of alphbet string which are used
for (type = 0; type < DATATYPE; type++){
if (matchTable[type] == TRUE){
for (j = 1; j <= bitStringCount; j++){
for (in = 0, bitDo = 1; bitDo <= BITSIZE; bitDo++){
if (alphbetString[type][j] % 2 == 1){
in = 1;
}
alphbetString[type][j] /= 2;
revAlphbetString[type][j] *= 2;
if (in == 1){
revAlphbetString[type][j]++;
in = 0;
}
}
}
}
}
prevRow[1]++;
for (i = 1; i <= n; i++){
for (j = 1; j <= bitStringCount; j++){
tempX[j] = prevRow[j] & revAlphbetString[stringB[i]][j];
}// Process AND operation
if (m%BITSIZE != 0){
/*for (j = 1, temp = 0; j <= m%BITSIZE; j++){
temp += (int) pow((float) 2, BITSIZE - j);
}*/
temp = 1;
prevRow[bitStringCount] &= temp;
}
for (j = 1, carry = 0; j <= bitStringCount; j++){
if ((prevRow[j] + tempX[j] < (int) pow((float) 2, BITSIZE) && carry == 0) || (prevRow[j] + tempX[j] + 1 < (int) pow((float) 2, BITSIZE) && carry == 1)){
tempX[j] += prevRow[j];
if (carry == 1){
tempX[j]++;
}
carry = 0;
}
else{
tempX[j] += prevRow[j];
if (carry == 1){
tempX[j]++;
}
carry = 1;
}
}
for (j = 1; j <= bitStringCount; j++){
prevRow[j] = tempX[j] | (prevRow[j] & (((int) pow((float) 2, BITSIZE) - 1) - revAlphbetString[stringB[i]][j]));
}// Process OR operation
if (m%BITSIZE != 0){
temp = 1;
prevRow[bitStringCount] &= temp;
}
}
for (i = 1; i <= bitStringCount; i++){
for (j = 1; j <= BITSIZE; j++){
if (m%BITSIZE != 0 && (i == bitStringCount) && (j > m%BITSIZE)){
break;
}
if (prevRow[i] % 2 == 0){
LCS++;
}
prevRow[i] /= 2;
}
}// Find the LCS
free(alphbetString);
free(revAlphbetString);
free(tempX);
free(prevRow);
return LCS;
}